/* visStreamTube.h
 * This file generates streamtubes in the flow field.
 * The class visStreamTube is a derived class of the 
 * class visStreamsurface
*/

#ifndef VIS_STREAMTUBE_H
#define VIS_STREAMTUBE_H

#include "visStreamsurface.h"

namespace visualization
{
/* Define the visStreamTube class
*/
//============================================
class visStreamTube : public visStreamsurface
//============================================
{
public:
	/* Constructor
	*/
	//==========================================================
	visStreamTube(visualization::Model *m) : visStreamsurface(m)
	//==========================================================
	{
		//The default streamtube has variant radius;
		invariantRadius = 0;
	}

	/*
	*/
	//===============
	~visStreamTube()
	//===============
	{}

	/*
	*/
	//============================
	void setInvariantTubeRadius()
	{
		invariantRadius = 1;
	}
	//============================

	/* This method determines some parameters for tubes, such as
	** thire centers, radius, and number of segments on the circles.	
	** These parameters are passed to visStreamsurface::set#Sources(...),
	   saved in the vairable streamsurface[...].

	** centers     :  the centers of tubes
	** radius      :  the radius of tubes
	** nCenter, nRadius :  number of centers and radius, used for 
	                       validation of the two parameters
	** resolution  :  number of points on the circles of the tube.
	**                If it is less than 3, just set the value as 3
	*/
	//===============================================
	void setTubeSources(visualization::Point *center,
						int	   nCenter,
						double *radius, 
						int    nRadius,
						int    nSegment = resolution
						);
	//===============================================

	/*
	*/
	//============================================
	void calculateUCoordinate(std::vector<double> *tCenter,
							  double *uCoordinate, 
							  double r,
							  int flag);
	//============================================

	/* Calculate the points at the beginning of a tube given the 
	 * center and radius of the tube specified by user.
	 * tubeCenter : a pointer pointing to the center of the 
	 *              beginning of a tube
	 * nPoints    : resolution,that is,number of points on the beginng
	 *              circle of tube specified by user
	 * results    : used to save the coordinates of points
	 *              calculated
	 * index      : from which new results are supposed to begin to
	                be saved to resutls.
	*/
	//=========================================================
	void getPointsOntheCircle(visualization::Point *tubeCenter,
							  double radius,
							  int nPoints, 
							  double **results,
							  int &index);
	//=========================================================

	/* Integrate and calculate the streamlines forming
	 * each streamtube, and then Construct tubes
	*/
	//===================
	void constructTube();
	//===================

	/*
	*/
	//===============================================
	vector<visualization::Point> *getTheStreamtube();
	//===============================================	

private:
	// One closed streamsurface forms one streamtube
	//vector<visStreamsurface> streamTubes;

	//The number of streamtube
	int tubeNumber;

	//double *tubeCenter;
	//double *tubeRadius;
	//int nTubes;
	static const int resolution = 10;

	//Streamtube with radius of constant size, that is,
	//a degenerated streamtube resulting in a steamline.
	int invariantRadius;
};

}
#endif

